#include "officerw.h"
#include <QAxObject>

/******************************************************************************
*
*                           Word 读写
*
******************************************************************************/
class WordRW
{
public:
    explicit WordRW();
    void Open();                            //打开文件
    void Close();                           //关闭文件
    void Save();                            //保存文件
    bool SaveAs(const QString fileName);    //文件另存为
    bool SetMarks(const QString marks,
        const QString content);             //设置标签内容
    bool SetTitle(const QString marks,
        const QString content);             //插入标题
    void InsertTable(int nStart, int nEnd,  //插入表格
        int row, int colum);
    QAxObject* InsertTable(QString label, int row, int column);
private:
    QAxObject* m_word;          //Word 应用程序指针
    QAxObject* m_docs;          //文档集指针
    QAxObject* m_document;      //文档指针
    QAxObject* m_paragraph;     //文本段指针
};

/******************************************************************************
*
*                           Excel 读写
*
******************************************************************************/
class ExcelRW
{
public:
    explicit ExcelRW();

private:
    QAxObject* m_excel;         //Excel 应用程序指针
    QAxObject* m_works;         //工作簿集指针
    QAxObject* m_workBook;      //工作簿指针
    QAxObject* m_sheets;        //电子表格集指针
};

/******************************************************************************
*
*                           OfficeRW 类
*
******************************************************************************/
OfficeRW* OfficeRW::m_instance = nullptr;
std::mutex resource_mutex_officeRW;

OfficeRW* OfficeRW::GetInstance()
{
    if (nullptr == m_instance)
    {
        std::unique_lock<std::mutex> mymutex(resource_mutex_officeRW);
        if (nullptr == m_instance)
        {
            m_instance = new OfficeRW();
            static CGar_OfficeRW c1;
        }
    }
    return m_instance;
}

bool OfficeRW::Test()
{
    WordRW temWordRW;
    temWordRW.Open();
    //temWordRW.SetTitle("", "zxq");
    temWordRW.InsertTable("123", 5, 5);
    temWordRW.Save();
    temWordRW.Close();
    return false;
}

OfficeRW::OfficeRW()
{
    
}

CGar_OfficeRW::~CGar_OfficeRW()
{
    if (OfficeRW::m_instance)
    {
        delete OfficeRW::m_instance;
        OfficeRW::m_instance = nullptr;
    }
}

ExcelRW::ExcelRW()
{
    m_excel = nullptr;
    m_works = nullptr;
    m_workBook = nullptr;
    m_sheets = nullptr;
}

WordRW::WordRW()
{
    m_word = nullptr;
    m_docs = nullptr;
    m_document = nullptr;
    m_paragraph = nullptr;
}

/******************************************************************************
* @file 		Open
* @brief 		打开
* @param 		void
* @return 		void
* @note 		void
* @author 		zxq
* @date 		2021/01/05
******************************************************************************/
void WordRW::Open()
{
    m_word = new QAxObject();

    //使用 Word 打开
    if (!m_word->setControl("Word.Application"))
    {
        //若 Word 无法打开文件，则使用 WPS 打开
        if (!m_word->setControl("kwps.Application"))
        {
            QMessageBox::information(NULL, QObject::tr("error"), QObject::tr("Open word file failed !"));
            return void();
        }
    }

    //是否显示弹窗(即是否打开 Word 窗口)
    m_word->setProperty("Visible", false);

    //获取文档集
    m_docs = m_word->querySubObject("Documents");
    if (!m_docs)
    {
        QMessageBox::information(NULL, QObject::tr("error"), QObject::tr("Get word documents failed !"));
        return void();
    }

    //添加一个文档
    m_docs->dynamicCall("Add(void)");

    //指向当前活动的文档
    m_document = m_word->querySubObject("ActiveDocument");
}

/******************************************************************************
* @file 		Close
* @brief 		关闭
* @param 		void
* @return 		void
* @note 		void
* @author 		zxq
* @date 		2021/01/05
******************************************************************************/
void WordRW::Close()
{
    if (m_document)
    {
        m_document->dynamicCall("Close (bool)", true);      //关闭文本窗口
        if (m_document)
        {
            delete m_document;
        }
        m_document = nullptr;
    }
    if (m_word)
    {
        m_word->dynamicCall("Quit()");                      //退出 Word
        if (m_word)
        {
            delete m_word;
        }
        m_word = nullptr;
    }
}

/******************************************************************************
* @file 		Save
* @brief 		保存
* @param 		void
* @return 		void
* @note 		void
* @author 		zxq
* @date 		2021/01/05
******************************************************************************/
void WordRW::Save()
{
    m_document->dynamicCall("Save()");
}

/******************************************************************************
* @file 		SaveAs
* @brief 		另存为
* @param 		void
* @return 		bool        成功返回 true
*                           失败返回 false
* @note 		void
* @author 		zxq
* @date 		2021/01/05
******************************************************************************/
bool WordRW::SaveAs(const QString fileName)
{
    return m_document->dynamicCall("SaveAs (const QString)", fileName).toBool();
}

/******************************************************************************
* @file 		SetMarks
* @brief 		设置标签内容
* @param 		const QString marks
*               const QString content
* @return 		bool    成功返回 true
*                       失败返回 false
* @note 		void
* @author 		zxq
* @date 		2021/01/05
******************************************************************************/
bool WordRW::SetMarks(const QString marks, const QString content)
{
    QAxObject* temBookMarkCode = nullptr;
    temBookMarkCode = m_document->querySubObject("Bookmarks(QVariant)", marks);

    //选中标签，将字符  Textg 插入到标签的位置
    if (temBookMarkCode)
    {
        temBookMarkCode->dynamicCall("Select(void)");
        temBookMarkCode->querySubObject("Range")->setProperty("Text", content);
        return true;
    }

    return false;
}

bool WordRW::SetTitle(const QString marks, const QString content)
{
    QAxObject* temBookMarkCode = nullptr;
    temBookMarkCode = m_document->querySubObject("Bookmarks(QVariant)", marks);

    //选中标签
    if (temBookMarkCode)
    {
        temBookMarkCode->dynamicCall("Select(void)");
        temBookMarkCode->querySubObject("Range")->setProperty("Text", content + "\n");
        temBookMarkCode->querySubObject("Range")->dynamicCall("SetStyle(QVariant)", QString::fromUtf8("标题 3"));
        return true;
    }
    return false;
}

/******************************************************************************
* @file 		InsertTable
* @brief 		插入表格
* @param 		int nStart      开始位置
*               int nEnd        结束位置
*               int row         行
*               int colum       列
* @return 		void
* @note 		void
* @author 		zxq
* @date 		2021/01/05
******************************************************************************/
void WordRW::InsertTable(int nStart, int nEnd, int row, int colum)
{
    QAxObject* ptst = m_document->querySubObject("Range(long, long)", nStart, nEnd);

    QAxObject* pTable = m_document->querySubObject("Tables");
    QVariantList params;
    params.append(ptst->asVariant());
    params.append(row);
    params.append(colum);
    if (pTable)
    {
        pTable->dynamicCall("Add(QAxObject*, long, long)", params);
    }
}

QAxObject* WordRW::InsertTable(QString label, int row, int column)
{
    QAxObject* temBookMark = m_document->querySubObject("Bookmarks(QVariant)", label);
    if (temBookMark)
    {
        temBookMark->dynamicCall("Select(void)");
        QAxObject* selection = m_document->querySubObject("Selection");

        selection->dynamicCall("InsertAfter(QString&)", "n");
        selection->querySubObject("ParagraphFormat")->dynamicCall("Aligment", "wdAlignParagraphCenter");

        QAxObject* range = selection->querySubObject("Range");
        QAxObject* tables = m_document->querySubObject("Tavles");
        QAxObject* table = tables->querySubObject("Add(QVariant, int, int)", range->asVariant(), row, column);

        for (int i = 0; i <= 6; i++)
        {
            QString str = QString("Borders(-%1)").arg(i);
            QAxObject* borders = tables->querySubObject(str.toUtf8().constData());
            borders->dynamicCall("SetLineStyle(int)", 1);
        }
        return table;
    }

    return nullptr;
}
